package com.tengju.bff.interfaces.shared.servlet.realm;

import com.tengju.user.application.shared.ApplicationException;
import com.tengju.user.application.shared.ApplicationExceptionCode;
import com.tengju.user.application.shared.JwtUtil;
import com.tengju.user.domain.model.login.JwtToken;
import com.tengju.user.domain.model.login.LoginResult;
import com.tengju.user.domain.model.login.UserAccount;
import com.tengju.user.domain.model.login.UserType;
import com.tengju.user.domain.model.user.*;
import com.tengju.user.domain.shared.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.Resource;
import java.util.ArrayList;

/**
 * @author wuziyang
 */
@Slf4j
public class JwtRealm extends AuthorizingRealm {

    @Autowired
    private UserAccountRepository userAccountRepository;

    @Resource
    private UserInfoRepository userInfoRepository;

//    private static final String TEST_SECRET_KEY = "NYlTrVbUyoz0GfMh";

    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof JwtToken;
    }

    /**
     * 权限
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }

    /**
     * 认证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auth) throws AuthenticationException {
        String token = (String) auth.getCredentials();

        LoginDesc loginDesc ;
        LoginResult loginResult;


        if (StringUtils.isEmpty(token)) {
            throw ApplicationException.error(ApplicationExceptionCode.TOKEN_OVERDUE);
        }


        String username = JwtUtil.getUsername(token);
        UserAccount userAccount = userAccountRepository.queryUserAccount(username, UserType.USER);
        if (userAccount == null) {
            throw ApplicationException.error(ApplicationExceptionCode.TOKEN_OVERDUE);
        }
        //校验token
        JwtUtil.verify(token,username,userAccount.getPassword());
        loginResult = userAccountRepository.getTokenValue(token);
        if (loginResult == null) {
            loginDesc = userInfoRepository.getByUserId(userAccount.getUserId());
            if (loginDesc == null) {
                throw ApplicationException.error(ApplicationExceptionCode.TOKEN_OVERDUE);
            }
            loginResult = new LoginResult(loginDesc.getId(),
                    userAccount.getUsername(),
                    loginDesc.getNickName(),
                    loginDesc.getHeadImage(),
                    token,
                    loginDesc.getUserType(),
                    loginDesc.getUserIdCode(),
                    new ArrayList<>(),
                    new ArrayList<>(),
                    userAccount.getPassword(),
                    new ArrayList<>(),
                    null);
            //token过期 续时7天
            userAccountRepository.saveToken(token, JsonUtil.toJSONString(loginResult));
        }


        return new SimpleAuthenticationInfo(loginResult,token,getName());
    }
}
